import json
from abc import ABC, abstractmethod

from forward.api.admin.schemas.channel import ChannelOaMenusInSchema
from forward.exceptions.base import AppException
from forward.extend.pydantic.result_api import ResultAPI
from forward.http_base import HttpResp
from forward.utils.config import ConfigUtil
from forward.utils.tools import ToolsUtil
from forward.utils.wechat import WeChatUtil


class ChannelOaMenuService:
    """公众号菜单服务实现类"""

    async def detail(self):
        """菜单详情"""
        config = await ConfigUtil.get_val("oa_channel", "menus", "[]")
        if not config:
            return []
        config = ChannelOaMenusInSchema.model_validate(json.loads(config))
        return config.model_dump(by_alias=True)

    async def save(self, menus_in: ChannelOaMenusInSchema, is_publish: bool):
        """菜单保存"""
        print("menus_in", menus_in.model_dump())
        # return ""
        menus = menus_in.root
        # print("menus_in", menus)
        if len(menus) > 3:
            raise AppException(HttpResp.FAILED, msg="一级菜单超出限制(最多3个)")
        for menu in menus:
            item = menu.model_dump()
            menu_type = item.pop("menu_type")
            # 一级菜单
            if menu_type == 0:
                item.pop("sub_buttons")
                assert item.get("visit_type"), "一级菜单visitType数缺失"
                if item.get("visit_type") == "miniprogram":
                    assert item.get("app_id"), "一级菜单appId参数缺失"
                    assert item.get("url"), "一级菜单url数缺失"
                    assert item.get("page_path"), "一级菜单pagePath数缺失"
                else:
                    assert item.get("url"), "一级菜单url数缺失"
                    item.pop("app_id")
                    item.pop("page_path")
            # 子级菜单
            if menu_type == 1:
                item.pop("visit_type")
                sub_buttons = item.get("sub_buttons")
                assert sub_buttons, "子级菜单不能为空"
                if len(sub_buttons) > 5:
                    raise AppException(HttpResp.FAILED, msg="子级菜单超出限制(最多5个)")
                for sub in sub_buttons:
                    assert sub.get("visit_type"), "子级菜单visitType参数缺失!"
                    if sub.get("visit_type") == "miniprogram":
                        assert sub.get("app_id"), "子级菜单appId参数缺失"
                        assert sub.get("url"), "子级菜单url数缺失"
                        assert sub.get("page_path"), "子级菜单pagePath数缺失"
                    else:
                        assert sub.get("url"), "子级菜单url数缺失"
                        sub.pop("app_id")
                        sub.pop("page_path")
        await ConfigUtil.set(
            "oa_channel", "menus", json.dumps([menu.model_dump() for menu in menus])
        )
        if is_publish:
            client = await WeChatUtil.official()
            menus_dict = [menu.model_dump() for menu in menus]
            print("menus_dict", menus_dict)
            menus_1 = [
                {"type": "click", "name": "今日歌曲", "key": "V1001_TODAY_MUSIC"},
                {
                    "name": "菜单",
                    "sub_button": [
                        {
                            "type": "view",
                            "name": "搜索",
                            "url": "http://www.soso.com/",
                        },
                        {
                            "type": "click",
                            "name": "赞一下我们",
                            "key": "V1001_GOOD",
                        },
                    ],
                },
            ]

            client.menu.create({"button": menus_1})
        return ResultAPI()

    @classmethod
    async def instance(cls):
        """实例化"""
        return cls()
